package com.yw.android.common.api;

import com.yw.android.common.utils.FLOG;
import com.yw.android.common.utils.LOG;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class ApiService<T> {
    /**
     * 标签
     */
    private static final String TAG = "ApiService";
    private static ApiService mInstance;
    /**
     * 缓存API
     */
    private Map<ApiConf, T> mApiCache = new HashMap<ApiConf, T>();

    private ApiService() {
    }

    public static ApiService getInstance() {
        if (mInstance == null)
            synchronized (TAG) {
                if (mInstance == null)
                    mInstance = new ApiService();
            }
        return mInstance;
    }

    /**
     * 对外暴露的接口 每个AppConf对应一个AppService 并做缓存
     *
     * @param mApiConf
     * @param mApiClass
     * @return
     */
    public T getInstanceApi(ApiConf mApiConf, Class<T> mApiClass) {
        ApiService mTmpInstance = getInstance();
        if (mTmpInstance == null) {
            FLOG.e("[ApiConf : " + mApiConf + "][Class : " + mApiClass.getSimpleName() + "] init error!!!");
            return null;
        }
        return (T) mTmpInstance.getApi(mApiConf, mApiClass);
    }

    private T createNewApi(final ApiConf mApiConf, Class<T> mApiClass) {
        LOG.i("[ApiConf : " + mApiConf + "][Class : " + mApiClass.getSimpleName() + "] init AppService start...");
        OkHttpClient.Builder mBuilder = new OkHttpClient.Builder()
                .readTimeout(mApiConf.readTimeOut, TimeUnit.MILLISECONDS)
                .writeTimeout(mApiConf.writeTimeOut, TimeUnit.MILLISECONDS)
                .connectTimeout(mApiConf.connectTimeOut, TimeUnit.MILLISECONDS)
                .cache(mApiConf.getCacheFile());
        if (mApiConf.getLogInterceptor() != null) {
            mBuilder.addInterceptor(mApiConf.getLogInterceptor());
        }

        if (mApiConf.mLocalInterceptor != null) {
            mBuilder.addInterceptor(mApiConf.mLocalInterceptor);
        }

        if (mApiConf.mNetInterceptor != null) {
            mBuilder.addNetworkInterceptor(mApiConf.mNetInterceptor);
        }

        if (mApiConf.mSSLSocketFactory != null) {
            mBuilder.sslSocketFactory(mApiConf.mSSLSocketFactory);
        }

        OkHttpClient okHttpClient = mBuilder.build();


        Retrofit.Builder mRetrofitBuilder = new Retrofit.Builder()
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(mApiConf.host);

        if (mApiConf.mCustomConverter != null) {
            mRetrofitBuilder.addConverterFactory(mApiConf.mCustomConverter);
        } else {
            mRetrofitBuilder.addConverterFactory(GsonConverterFactory.create());
        }

        Retrofit retrofit = mRetrofitBuilder.build();
        LOG.i("[ApiConf : " + mApiConf + "][Class : " + mApiClass.getSimpleName() + "] init AppService stop...");
        return retrofit.create(mApiClass);
    }

    private T getApi(ApiConf mApiConf, Class<T> mApiClass) {
        if (!mApiCache.containsKey(mApiConf))
            synchronized (TAG) {
                if (!mApiCache.containsKey(mApiConf))
                    mApiCache.put(mApiConf, createNewApi(mApiConf, mApiClass));
            }
        return mApiCache.get(mApiConf);
    }
}
